package balmysundaycandy.morelowlevel.sample.controller.datastore;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Logger;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;

import balmysundaycandy.extention.datastore.AsyncDatastoreService;
import balmysundaycandy.extention.datastore.impl.AsyncDatastoreServiceImpl;
import balmysundaycandy.more.low.level.datastore.DatastoreOperations;
import balmysundaycandy.morelowlevel.sample.controller.PathElement;
import balmysundaycandy.morelowlevel.sample.services.QueryService;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.DatastorePb.QueryResult;

public class IndexController extends Controller {

	Logger logger = Logger.getLogger(IndexController.class.getSimpleName());
	QueryService queryService = new QueryService();

	AsyncDatastoreService asyncDatastoreService = new AsyncDatastoreServiceImpl();

	@Override
	protected Navigation run() {
		runQuery();

		return forward(PathElement.JSP_PATH + "/datastore/index.jsp");
	}

	void getWithAsyncDatastoreService() {
		Key key = KeyFactory.createKey("ASYNC", 5L);

		long asyncCallStart = System.currentTimeMillis();
		Future<Entity> future = null;
		try {
			future = asyncDatastoreService.get(key);
		} catch (EntityNotFoundException e1) {
			e1.printStackTrace();
		}
		long asyncCallEnd = System.currentTimeMillis();

		int notDoneCount = 0;
		while (!future.isDone()) {
			++notDoneCount;
		}
		long callEnd = System.currentTimeMillis();

		String responseString = null;
		try {
			responseString = future.get().toString();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		requestScope("notDoneCount", notDoneCount);
		requestScope("asyncCallTimeMills", asyncCallEnd - asyncCallStart);
		requestScope("callEndTimeMills", callEnd - asyncCallStart);
		requestScope("responseString", responseString);

		System.out.print(notDoneCount);
		System.out.print("\t");
		System.out.print(asyncCallEnd - asyncCallStart);
		System.out.print("\t");
		System.out.print(callEnd - asyncCallStart);
		System.out.println();

	}

	void runQuery() {
		ApiConfig apiConfig = new ApiConfig();
		apiConfig.setDeadlineInSeconds(10d);

		long asyncCallStart = System.currentTimeMillis();
		Future<QueryResult> future = DatastoreOperations.RUN_QUERY.callAsync(queryService.getDefaultQuery(), apiConfig);
		long asyncCallEnd = System.currentTimeMillis();

		long callEnd = 0L;

		String responseString = null;
		try {
			responseString = future.get().toFlatString();
			callEnd = System.currentTimeMillis();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		requestScope("asyncCallTimeMills", asyncCallEnd - asyncCallStart);
		requestScope("callEndTimeMills", callEnd - asyncCallStart);
		requestScope("responseString", responseString);
	}

}
